﻿using SuperX.Common.Log;
using SuperX.MiddlewareBase;
using RabbitMQ.Client;
using System;
using System.Threading;
using System.Threading.Tasks;

namespace SuperX.DataCenterService.RabbitMQ.Model
{
    public class RabbitHost : ServerBase
    {
        public RabbitHost(RabbitHostConfig hostConfig)
        {
            Name = hostConfig.Name;
            HostConfig = hostConfig;
        }

        public RabbitHostConfig HostConfig { get; set; }

        /// <summary>
        /// MQ连接工厂
        /// </summary>
        private ConnectionFactory RabbitMqFactory { get; set; }

        /// <summary>
        /// 连接对象
        /// </summary>
        public IConnection Connection { get; set; }

        public override void Init()
        {
            //初始化主机
            RabbitMqFactory = new ConnectionFactory()
            {
                HostName = HostConfig.HostIP,
                UserName = HostConfig.UserName,
                Password = Helper.Encryption.Decode(HostConfig.Password),//将密码解密
                Port = HostConfig.Port,
                VirtualHost = HostConfig.VirtualHost,
                NetworkRecoveryInterval = HostConfig.NetworkRecoveryInterval,
                AutomaticRecoveryEnabled = HostConfig.AutomaticRecoveryEnabled,
                RequestedHeartbeat = HostConfig.Heartbeat,
                TopologyRecoveryEnabled = HostConfig.TopologyRecoveryEnabled,
                RequestedConnectionTimeout = HostConfig.RequestedConnectionTimeout,
                RequestedChannelMax = HostConfig.ChannelMax,
                RequestedFrameMax = HostConfig.RequestedFrameMax,
                UseBackgroundThreadsForIO = HostConfig.UseBackgroundThreadsForIO,
                ContinuationTimeout = TimeSpan.FromMilliseconds(HostConfig.ContinuationTimeout)
            };
            BuildClient();
            TryContinueConnect();
            foreach (RabbitChannel ChannelItems in Channels)
            {
                if (string.IsNullOrEmpty(ChannelItems.TagName)) continue;
                if (string.IsNullOrEmpty(ChannelItems.ExchangeName))
                    ChannelItems.ExchangeName = $"{HostConfig.PublishPrefix}.DataCenterExchange";
                if (string.IsNullOrEmpty(ChannelItems.RoutingKey))
                    ChannelItems.RoutingKey = $"{HostConfig.PublishPrefix}.{Name}.{ChannelItems.Name}";
                //初始化通道
                ChannelItems.Init();
            }
        }

        private void TryContinueConnect()
        {
            Task.Factory.StartNew(() =>
            {
                while (Connection == null)
                {
                    try
                    {
                        BuildClient();
                    }
                    catch (Exception ex)
                    {
                        Logger.Error(FullName + "：连接异常:" + ex.Message);
                    }

                    if (Connection == null)
                    {
                        Logger.Warn("请检查网络或者检查服务是否启动。");
                        Thread.Sleep(2000);
                    }
                }
            });
        }

        private void BuildClient()
        {
            try
            {
                Connection = RabbitMqFactory.CreateConnection();
                Logger.Info($"RabbitMQ：{Name} 连接成功！");
            }
            catch (Exception e)
            {
                Logger.Error($"构建RaabbitMQ：{Name} 客户端失败:{e.Message}");
                return;
            }
        }

        public override void Stop()
        {
            base.Stop();
            Connection?.Close();
            Connection?.Dispose();
        }
    }
}